#pragma once

//#include <jni.h>
#include <map>

namespace gtl
{

namespace jni
{

class jstr;
class jstrs;

//class _jstringArray : public _jobjectArray	{};
//
//typedef _jstringArray*	jstringArray;

namespace detail
{

template<class T>
class type
{
	friend class auto_creator;

protected:
	static std::map<std::string, const char*> m_types;

protected:
	struct creator
	{
		creator()
		{
			type<void>::m_types[typeid(void).name()]		  = "V";
			type<void>::m_types[typeid(int).name()]			  = "I";
			type<void>::m_types[typeid(bool).name()]		  = "Z";
			type<void>::m_types[typeid(const char*).name()]   = "Ljava/lang/String;";
			type<void>::m_types[typeid(jstr).name()]		  = "Ljava/lang/String;";
			type<void>::m_types[typeid(jstrs).name()]		  = "[Ljava/lang/String;";
			//type<void>::m_types[typeid(jstring).name()]		  = "Ljava/lang/String;";
			//type<void>::m_types[typeid(jstringArray).name()]  = "[Ljava/lang/String;";
			//type<void>::m_types[typeid(jbooleanArray).name()] = "[Z";
		}
	};

	static creator m_creator;
};

template<class T>
std::map<std::string, const char*> type<T>::m_types;

template<class T>
typename type<T>::creator type<T>::m_creator;

class auto_creator
{
	auto_creator()
	{
		(void)type<void>::m_creator;
	}
};

} // end of namespace detail

template<class T>
class jtype : detail::type<void>
{
public:
	static const char* type()
	{
		std::string name = typeid(T).name();
		if(strncmp(name.c_str(), "enum", 4) == 0)
			return m_types["int"];

		return m_types[name];
	}

	static void reg(const char* type)
	{
		m_types[typeid(T).name()] = type;
	}
};

} // end of namespace jni

} // end of namespace gtl
